from SCRIBES.SignalConnectionManager import SignalManager
import ctags
from ctags import CTags, TagEntry
from Utils import get_instance, focus_window_and_set_cursor

class Ctags(SignalManager):

	def __init__(self, manager, editor):
		SignalManager.__init__(self)
		self.__init_attributes(manager, editor)
		self.connect(manager, "activate", self.__activate_cb)
		self.connect(manager, "destroy", self.__destroy_cb)

	def __init_attributes(self, manager, editor):
		self.__manager = manager
		self.__editor = editor
		self.__tagsfilename = None
		self.__pattern = None
		self.__new_instance = None
		return

	def __ctags(self):
		title = "Definitions"
		if not self.__tagsfilename and not self.__find_tagsfile():
			message = "No tags file" 
			self.__editor.update_message(message, "no", 10)
			return False
		try:
			symbol = self.__editor.selected_text
		except TypeError, e:
			message = """No text selected"""
			self.__editor.update_message(message, "no", 10)
			return False

		try:
			tagfile = CTags(self.__tagsfilename)
		except:
			message = "Could not open tags file %s." % self.__tagsfilename
			self.__editor.update_message(message, "no", 10)
			return False

		entry = TagEntry()
		if tagfile.find(entry, symbol, ctags.TAG_FULLMATCH | ctags.TAG_OBSERVECASE):
			from os.path import join
			tag = {'file':"file://%s" % join(self.__tagsfilefolder, entry['file']),
				'pattern':entry['pattern'].strip('/'), 'kind':entry['kind']}
			status = tagfile.findNext(entry)
			if status:
				## There's more than one file that has the tag. Display
				## a list so the user can choose.
				tags = [tag,
					{'file':"file://%s" % join(self.__tagsfilefolder, entry['file']),
					'pattern':entry['pattern'].strip('/'), 'kind':entry['kind']}]
				while tagfile.findNext(entry):
					tags.append({'file':"file://%s" % join(self.__tagsfilefolder, entry['file']), 
						'pattern':entry['pattern'].strip('/'), 'kind':entry['kind']})
				self.__manager.show(tags)
			else:
				## There's only one file with the tag. Open the file
				## with the tag, or raise the window if it is already
				## opened.
				## Check if the file is already open.
				instance = get_instance(self.__editor, tag['file'])
				if not instance:
					# If we got here, we need to open the file.
					self.__editor.open_file(tag['file'])
					instance = get_instance(self.__editor, tag['file'])
					# Now we also need to set the cursor to the line the tag is on.
					if instance:
						self.__new_instance = instance
						self.__pattern = tag['pattern']
						self.__new_instance.connect("loaded-file", self.__loaded_file_cb)
				else:
					focus_window_and_set_cursor(self.__editor, tag, instance)

		return False
	
	def __loaded_file_cb(self, *args):
		import gobject
		gobject.timeout_add(1000,
		    focus_window_and_set_cursor, self.__editor, 
		        {'pattern':self.__pattern}, self.__new_instance)
		return False		
	
	def __find_tagsfile(self):
		"""Go up the directory tree and find a file called tags."""
		from os.path import join, split, exists
		current_folder = split(self.__editor.filename)[0]
		while not exists(join(current_folder, 'tags')) and current_folder != '/':
			current_folder = split(current_folder)[0]
		tagsfilename = join(current_folder, 'tags')
		if not exists(tagsfilename):
			self.__message = "No tags file found."
			return False
		self.__tagsfilename = tagsfilename
		self.__tagsfilefolder = current_folder
		return True
	
	def __activate_cb(self, *args):
		self.__ctags()
		return False

	def __destroy_cb(self, *args):
		self.disconnect()
		del self
		return False

